package com.filepd.utils;

import cn.hutool.core.lang.Dict;
import cn.hutool.http.Header;
import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.filepd.entity.BlockInfo;
import com.filepd.entity.Enum.network;
import com.filepd.entity.File;
import com.google.gson.Gson;
import lombok.extern.slf4j.Slf4j;
import org.fisco.bcos.sdk.crypto.CryptoSuite;
import org.fisco.bcos.sdk.crypto.keypair.CryptoKeyPair;
import org.fisco.bcos.sdk.model.CryptoType;
import org.junit.Test;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;


@Service
@Slf4j
public class WeBASEUtils {

    // user的私钥,没导入数据库前不要改
    private final String userAddress = "0xae25f5e03713f90d596dcbc8429e321b56e03197";

    private final String funcName = "getAll";

    private final String ABI = IOUtil.readResourceAsString("abi/FileContract.abi");

    private final String contractName = "FileContract";

    private final String contractAddress = "0x370190a257ba9d14720c88685a1e4db406ba5c1d";

    private static final String net = network.SERVEL_NETWORK.getNetWork();

    /**
     * 请求
     *
     * @param userAddress
     * @param funcName
     * @param funcParam
     * @param ABI
     * @param contractName
     * @param contractAddress
     * @return
     */
    public static Dict requsert(
            String userAddress,
            String funcName,
            List funcParam,
            String ABI,
            String contractName,
            String contractAddress) {
        JSONArray abiJSON = JSONUtil.parseArray(ABI);
        JSONObject data = JSONUtil.createObj();
        data.set("groupId", "1"); //群组ID
        data.set("user", userAddress); //用户地址
        data.set("contractName", contractName); //合约名称
        data.set("version", "");  //cns版本
        data.set("funcName", funcName);  //方法名
        data.set("funcParam", funcParam);  //方法参数
        data.set("contractAddress", contractAddress); //合约地址
        data.set("contractAbi", abiJSON);  //合约编译后生成的abi文件内容
        data.set("useAes", false);
        data.set("cnsName", ""); //cns名称
        String dataString = JSONUtil.toJsonStr(data);
        String responseBody = HttpRequest.post(net+":5002/WeBASE-Front/trans/handle")
                .header(Header.CONTENT_TYPE, "application/json")
                .body(dataString)
                .execute()
                .body();
        Dict retDict = new Dict();
        retDict.set("result", responseBody);
        return retDict;
    }

    /**
     * 请求Get最新的交易
     */
    public File get() {
        Dict result = WeBASEUtils.requsert(userAddress, funcName, null, ABI, contractName, contractAddress);
        JSONObject resBody = JSONUtil.parseObj(result);

        String str = resBody.getStr("result");
        String[] split = str.split(",");
        str.replaceAll("\"", "");
        File file = new File();
        file.setUserName(split[0]);
        file.setFileName(split[1]);
        file.setFileSize(split[2]);
        file.setFileType(split[3]);
        return file;
    }

    /**
     * 请求Get最新的交易
     */
    @Test
    public void getTest() {
        Dict result = WeBASEUtils.requsert(userAddress, funcName, null, ABI, contractName, contractAddress);
        JSONObject resBody = JSONUtil.parseObj(result);

        String str = resBody.getStr("result");
        String[] split = str.split(",");
        str.replaceAll("\"", "");
        File file = new File();
        file.setUserName(split[0]);
        file.setFileName(split[1]);
        file.setFileSize(split[2]);
        file.setFileType(split[3]);
        log.info(String.valueOf(file));
    }


    /**
     * 请求set方法
     */
    public JSONObject set(String userName, String fileName, String fileSize, String fileType) {

        ArrayList funcParam = new ArrayList();
        funcParam.add(userName);
        funcParam.add(fileName);
        funcParam.add(fileSize);
        funcParam.add(fileType);
        Dict result = WeBASEUtils.requsert(userAddress, "setAll", funcParam, ABI, contractName, contractAddress);
        JSONObject resBody = JSONUtil.parseObj(result);

        log.info(String.valueOf(resBody));
        return resBody;
    }

    /**
     * 查询链上已经存在的用户  前置节点
     */
    @Test
    public void getAccountUtils() {
        String responseBody = HttpRequest
                .get(net+":5002/WeBASE-Front/privateKey/localKeyStores")
                .header(Header.CONTENT_TYPE, "application/json")
                .execute()
                .body();
        JSONArray jsonArray = JSONUtil.parseArray(responseBody);
        Object json = jsonArray.get(0);
        JSONObject jsonObject = JSONUtil.parseObj(json);
        Object userName = jsonObject.get("userName");
        log.info("\n获取到的用户名:" + userName);
    }
    /**
     * 分页查询合约接口
     */
    @Test
    public void contractListTests() {
        ArrayList funcParam = new ArrayList();
        funcParam.add("这是新的测试");

        Dict result = WeBASEUtils.requsert(userAddress, "setName", funcParam, ABI, contractName, contractAddress);
        JSONObject resBody = JSONUtil.parseObj(result);
        log.info(String.valueOf(resBody));

    }

    /**
     * 获取当前交易总量
     */
    @Test
    public void getTransNum() {
        String responseBody = HttpRequest
                .get(net+":5002/WeBASE-Front/" + 1 + "/web3/transaction-total")
                .header(Header.CONTENT_TYPE, "application/json")
                .execute()
                .body();
        log.info(responseBody);

    }

    /**
     * 测试用户上链
     */
    @Test
    public void test1(){
        String s = PublicAndPrivateKey_generationUtils("da");

    }
    /**
     * 生成外部账户
     * 在前置节点中
     */

    public String PublicAndPrivateKey_generationUtils(String userName) {
        CryptoSuite cryptoSuite = new CryptoSuite(CryptoType.ECDSA_TYPE);
        CryptoKeyPair cryptoKeyPair = cryptoSuite.createKeyPair();
        //生成私钥
        String privateKey = cryptoKeyPair.getHexPrivateKey();
        //用户名
        // TODO 注册用户传给userName 顺便保存数据进数据库

        JSONObject data = JSONUtil.createObj();
        data.set("privateKey", privateKey);

        data.set("userName", userName);
        String dataString = JSONUtil.toJsonStr(data);
        String responseBody = HttpRequest.get(
                        net+":5002/WeBASE-Front/privateKey/import?userName="
                                + userName
                                + "&privateKey="
                                + privateKey + "")
                .header(Header.CONTENT_TYPE, "application/json")
                .body(dataString)
                .execute()
                .body();
        Dict retDict = new Dict();
        retDict.set("result", responseBody);

        log.info(responseBody);
        return responseBody;
    }

    /**
     * 获取所有区块
     * 神奇的 :http://t.csdnimg.cn/SAZ7A教程
     * 先获取验证码 -->登录-->获取所有区块
     */
    public String getBlockAll() {
        // groupID = 1  pageNumber = 1  pageSize = 10
        String request = HttpRequest
                .get(net+":5000/mgr/WeBASE-Node-Manager/transaction/transList/1/1/10")
                .execute()
                .body();
        log.info("Request: " + request );

        String json = new Gson().toJson(request);

        return String.valueOf(json);
    }

    /**
     * 获取所有节点
     * @return
     */
    public String getPointAll() {
        // groupID = 1  pageNumber = 1  pageSize = 10
        String request = HttpRequest
                .get(net+":5000//mgr/WeBASE-Node-Manager/precompiled/consensus/list?groupId=" + 1 +"&pageNumber=" + 1 +"&pageSize=" + 10)
                .execute()
                .body();
        log.info("Request: " + request );

        String json = new Gson().toJson(request);

        return String.valueOf(json);
    }


    /**
     * 获取对应区块高的详细信息
     *
     * @param Blocknumber
     * @return
     */
    public BlockInfo getBlockNumber(Integer Blocknumber) {

        String request = HttpRequest
                .get(net + ":5002/WeBASE-Front/1/web3/blockByNumber/" + Blocknumber)
                .execute()
                .body();
        log.info("Request: " + request);
        JSONObject entries = new JSONObject(request);
        BlockInfo bean = JSONUtil.toBean(entries, BlockInfo.class);

        return bean;
    }

    /**
     * 获取对应区块Hash的详细信息
     *
     * @param blockHash
     * @return
     */
    public BlockInfo getBlockHash(String blockHash) {

        String request = HttpRequest
                .get(net + ":5002/WeBASE-Front/1/web3/blockByHash/" + blockHash)
                .execute()
                .body();
        log.info("Request: " + request);
        JSONObject entries = new JSONObject(request);
        BlockInfo bean = JSONUtil.toBean(entries, BlockInfo.class);

        return bean;
    }




}